package com.stars.easyms.base.util;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 时间日期工具类
 *
 * @author guoguifang
 * @date 2018-10-19 10:07
 * @since 1.0.0
 */
public final class TimeUtil {

    private static final Logger logger = LoggerFactory.getLogger(TimeUtil.class);

    public static final int CHINESE = 0;
    public static final int ENGLISH = 1;
    public static final int MILLISECOND = 0;
    public static final int SECOND = 1;
    public static final int MINUTE = 2;
    public static final int HOUR = 3;
    public static final int DAY = 4;

    private static final Pattern PATTERN = Pattern.compile("([-+]?)(?:([0-9]{1,4})[dD])?(?:([0-9]{1,5})[hH])?(?:([0-9]{1,7})[mM])?(?:([0-9]{1,9})[sS])?(?:([0-9]{1,12})[mM][sS])?");
    private static final int DAY_MILLIS = 86400000;
    private static final int HOUR_MILLIS = 3600000;
    private static final int MINUTE_MILLIS = 60000;
    private static final int SECOND_MILLIS = 1000;

    /**
     * 毫秒转化天时分秒毫秒
     *
     * @param ms       毫秒数
     * @param language 使用TimeUtil.CHINESE 或者 TimeUtil.ENGLISH
     * @return String 时间字符串(--天--小时--分--秒--毫秒)
     */
    public static String formatTime(Long ms, int language, int point) {

        String daySuffix;
        String hourSuffix;
        String minuteSuffix;
        String secondSuffix;
        String milliSecondSuffix;
        switch (language) {
            case CHINESE:
                daySuffix = " 天 ";
                hourSuffix = " 小时 ";
                minuteSuffix = " 分 ";
                secondSuffix = " 秒 ";
                milliSecondSuffix = " 毫秒 ";
                break;
            case ENGLISH:
            default:
                daySuffix = " days ";
                hourSuffix = " hours ";
                minuteSuffix = " minutes ";
                secondSuffix = " seconds ";
                milliSecondSuffix = " milliSeconds ";
        }

        StringBuilder sb = new StringBuilder();
        if (ms == null || ms == 0) {
            return sb.append(0).append(milliSecondSuffix).toString();
        }

        Integer ss = 1000;
        Integer mi = ss * 60;
        Integer hh = mi * 60;
        Integer dd = hh * 24;

        Long day = ms / dd;
        Long hour = (ms - day * dd) / hh;
        Long minute = (ms - day * dd - hour * hh) / mi;
        Long second = (ms - day * dd - hour * hh - minute * mi) / ss;
        Long milliSecond = ms - day * dd - hour * hh - minute * mi - second * ss;


        if (day > 0 && point <= DAY) {
            sb.append(day).append(daySuffix);
        }
        if (hour > 0 && point <= HOUR) {
            sb.append(hour).append(hourSuffix);
        }
        if (minute > 0 && point <= MINUTE) {
            sb.append(minute).append(minuteSuffix);
        }
        if (second > 0 && point <= SECOND) {
            sb.append(second).append(secondSuffix);
        }
        if (milliSecond > 0 && point <= MILLISECOND) {
            sb.append(milliSecond).append(milliSecondSuffix);
        }
        return sb.toString();
    }

    /**
     * 把字符串的时间转换成毫秒单位的数字
     * @param text 字符串的时间
     * @return 毫秒单位的数字
     */
    public static Long parseToMilliseconds(String text) {
        if (StringUtils.isBlank(text)) {
            return null;
        }
        if (StringUtils.isNumeric(text)) {
            return Long.parseLong(text) * 1000;
        }
        Matcher matcher = PATTERN.matcher(text);
        if ((matcher.matches())) {
            String dayMatch = matcher.group(2);
            String hourMatch = matcher.group(3);
            String minuteMatch = matcher.group(4);
            String secondMatch = matcher.group(5);
            String millisecondMatch = matcher.group(6);
            long daysAsMilliseconds = 0;
            long hoursAsMilliseconds = 0;
            long minutesAsMilliseconds = 0;
            long secondsAsMilliseconds = 0;
            long milliseconds = 0;
            if (dayMatch != null) {
                daysAsMilliseconds = Long.parseLong(dayMatch) * 86400000;
            }
            if (hourMatch != null) {
                hoursAsMilliseconds = Long.parseLong(hourMatch) * 3600000;
            }
            if (minuteMatch != null) {
                minutesAsMilliseconds = Long.parseLong(minuteMatch) * 60000;
            }
            if (secondMatch != null) {
                secondsAsMilliseconds = Long.parseLong(secondMatch) * 1000;
            }
            if (millisecondMatch != null) {
                milliseconds = Long.parseLong(millisecondMatch);
            }
            long result = daysAsMilliseconds + hoursAsMilliseconds + minutesAsMilliseconds + secondsAsMilliseconds + milliseconds;
            return "-".equals(matcher.group(1)) ? -1 * result : result;
        }
        logger.error("Text({}) parse milliseconds failure!", text);
        return null;
    }

    /**
     * 把毫秒单位的数字转换成字符串的时间
     * @param milliseconds 毫秒单位的数字
     * @return 字符串的时间
     */
    public static String parseFromMilliseconds(long milliseconds) {
        StringBuilder sb = new StringBuilder();
        if (milliseconds >= DAY_MILLIS) {
            long days = milliseconds / DAY_MILLIS;
            sb.append(days).append("d");
            milliseconds = milliseconds - days * DAY_MILLIS;
        }
        if (milliseconds >= HOUR_MILLIS) {
            long hours = milliseconds / HOUR_MILLIS;
            sb.append(hours).append("h");
            milliseconds = milliseconds - hours * HOUR_MILLIS;
        }
        if (milliseconds >= MINUTE_MILLIS) {
            long minutes = milliseconds / MINUTE_MILLIS;
            sb.append(minutes).append("m");
            milliseconds = milliseconds - minutes * MINUTE_MILLIS;
        }
        if (milliseconds >= SECOND_MILLIS) {
            long seconds = milliseconds / SECOND_MILLIS;
            sb.append(seconds).append("s");
            milliseconds = milliseconds - seconds * SECOND_MILLIS;
        }
        if (milliseconds >= 0) {
            sb.append(milliseconds).append("ms");
        }
        return sb.toString();
    }

    private TimeUtil() {
        super();
    }

}
